package org.shoukaiseki.common.utils;

import java.math.BigDecimal;
import java.math.RoundingMode;

public class CostMathUtils {

    public static final BigDecimal ZERO_POINT_ZERO_ONE =new BigDecimal("0.01");

    /**
     * 乘法运算,null作为0处理
     * @param args
     * @return  否则返回乘后结果
     */
    public static BigDecimal multipleMultiplyNullIsZero(BigDecimal... args){
        if (StringUtils.isEmpty(args)) {
            return BigDecimal.ZERO;
        }
        BigDecimal tmp=ifNullToZero(args[0]);
        for (int i = 1; i < args.length; i++) {
            BigDecimal arg = args[i];
            tmp=multiplyNullIsZero(tmp,arg);
        }
        return tmp;
    }

    /**
     * 乘法运算,null作为0处理
     * @param a
     * @param b
     * @return  否则返回乘后结果
     */
    public static BigDecimal multiplyNullIsZero(BigDecimal a,BigDecimal b){
        if (a==null||b==null) {
            return BigDecimal.ZERO;
        }
        return a.multiply(b);
    }

    /**
     * 乘法,会转换成 BigDecimal
     * @param a
     * @param b
     * @param <T>
     * @return
     */
    public static <T extends Number>BigDecimal multiplyNullIsZero(T a,T b){
        if(a==null||b==null){
            return BigDecimal.ZERO;
        }
        return multiplyNullIsZero(ifNullToZero(a),ifNullToZero(b));
    }

    public static BigDecimal multiplyNullIsZero(String a,String b){
       return  multiplyNullIsZero(new BigDecimal(a),new BigDecimal(b));
    }


    /**
     * a/b
     * @param a                  被除数
     * @param b                  除数
     * @param <T>                a/b
     * @return
     */
    public static <T extends Number>BigDecimal divideNullIsZero(T a,T b){
        return divideNullIsZero(a,b,2,BigDecimal.ZERO);
    }

    /**
     * a/b
     * @param a                  被除数
     * @param b                  除数
     * @param scale              小数位数
     * @param <T>                a/b
     * @return          如果有个值为null或者0则返回0
     */
    public static <T extends Number>BigDecimal divideNullIsZero(T a,T b,int scale){
        return divideNullIsZero(a,b,scale,BigDecimal.ZERO);
    }

    /**
     * a/b
     * @param a                  被除数
     * @param b                  除数
     * @param scale              小数位数
     * @param defaultValue       如果有个值为null或者0则返回该值
     * @param <T>                a/b
     * @return
     */
    public static <T extends Number>BigDecimal divideNullIsZero(T a,T b,int scale,BigDecimal defaultValue){
        if (a==null||b==null) {
            return defaultValue;
        }
        try {
            BigDecimal a1=(a instanceof BigDecimal)? (BigDecimal) a :BigDecimal.valueOf(a.doubleValue());
            BigDecimal b1=(b instanceof BigDecimal)? (BigDecimal) b :BigDecimal.valueOf(b.doubleValue());
            return a1.divide(b1, scale, BigDecimal.ROUND_HALF_UP);
        } catch (Exception e) {
            return defaultValue;
        }
    }

    public static BigDecimal divideNullIsZero(String a,String b){
      return  divideNullIsZero(new BigDecimal(a),new BigDecimal(b));
    }



    /**
     * 加法运算,null作为0处理
     * @param a
     * @param b
     * @return
     */
    public static <T extends Number>BigDecimal addNullIsZero(T a,T b){
        return ifNullToZero(a).add(ifNullToZero(b));
    }

    /**
     * 加法运算,null作为0处理
     * @param a
     * @param b
     * @return
     */
    public static BigDecimal addNullIsZero(String a,String b){
        return ifNullToZero(new BigDecimal(a)).add(ifNullToZero(new BigDecimal(b)));
    }


    /**
     * 加法运算,null作为0处理
     * @param vals 要相加的加数
     * @return
     */
    public static BigDecimal sum(BigDecimal... vals){
        BigDecimal sumValue = BigDecimal.ZERO;
        for (BigDecimal b : vals) {
            sumValue=addNullIsZero(sumValue,b);
        }
        return sumValue;
    }


    /**
     * 加法运算,null作为0处理
     * @param vals 要相加的加数
     * @return
     */
    public static Integer sumToInteger(Number... vals){
        BigDecimal sumValue = BigDecimal.ZERO;
        for (Number b : vals) {
            sumValue=addNullIsZero(sumValue,ifNullToZero(b));
        }
        return NumberUtils.convertNumberToTargetClass(sumValue,Integer.class);
    }

    /**
     * 加法运算,null作为0处理
     * @param vals 要相加的加数
     * @return
     */
    public static Long sumToLong(Number... vals){
        BigDecimal sumValue = BigDecimal.ZERO;
        for (Number b : vals) {
            sumValue=addNullIsZero(sumValue,ifNullToZero(b));
        }
        return NumberUtils.convertNumberToTargetClass(sumValue,Long.class);
    }

    /**
     * 加法运算,null作为0处理
     * @param a
     * @param b
     * @return
     */
    public static BigDecimal addNullIsZero(BigDecimal a,BigDecimal b){
        return ifNullToZero(a).add(ifNullToZero(b));
    }

    /**
     *  前面的为被减数,后面的为减数,第一个参数减去第二个参数
     * @param subtracted   a
     * @param subtrahend   b
     * @return  subtracted-subtrahend   a-b
     */
    public static BigDecimal subtractNullIsZero(BigDecimal subtracted,BigDecimal subtrahend){
        return ifNullToZero(subtracted).subtract(ifNullToZero(subtrahend));
    }

    public static BigDecimal subtractNullIsZero(String subtracted,String subtrahend){
       return  subtractNullIsZero(new BigDecimal(subtracted),new BigDecimal(subtracted));
    }


    public static BigDecimal  ifNullToZero(String a){
        if (StringUtils.isEmpty(a)) {
            return BigDecimal.ZERO;
        }
        return new BigDecimal(a);
    }

    /**
     * 如果为null则返回0,否则返回原有值
     * @param a
     * @return
     */
    public static BigDecimal  ifNullToZero(BigDecimal a){
        return a==null?BigDecimal.ZERO:a;
    }

    public static BigDecimal ifNullToZero(Number a){
        if(a==null){
            return BigDecimal.ZERO;
        }
        return a instanceof BigDecimal? (BigDecimal) a :BigDecimal.valueOf(a.doubleValue());
    }


    /**
     * 四舍五入
     * @param a
     * @param scale
     * @return
     */
    public static BigDecimal scaleHalfUp(Number a,int scale){
        return ifNullToZero(a).setScale(scale, RoundingMode.HALF_UP);
    }

    /**
     * 计算含税价格
     * @param notTaxCost
     * @param taxRate           税率百分比: 17 为17%税率
     */

    public static BigDecimal calcTaxCost(Number notTaxCost,Number taxRate){
        //含税成本=不含税成本*(税率百分比0.17+1)
        BigDecimal taxRateTmp = NumberUtils.isNullOrZero(taxRate) ? BigDecimal.ONE : multiplyNullIsZero(taxRate, 1.01);
        return multiplyNullIsZero(taxRateTmp,notTaxCost);
    }

    /**
     * 计算不含税价格
     * @param taxCost
     * @param taxRate
     */
    public static BigDecimal calcNotTaxCost(Number taxCost,Number taxRate){
        //不含税成本=含税成本*(1-税率百分比0.17)
        BigDecimal taxRateTmp = NumberUtils.isNullOrZero(taxRate) ? BigDecimal.ONE : subtractNullIsZero(BigDecimal.ONE,multiplyNullIsZero(taxRate, 0.01));
        return multiplyNullIsZero(taxRateTmp,taxCost);
    }

}
